package com.zlf.sb.demo.completableFuture;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.function.Predicate;

public class AsyncWorkflowEngine {
    public class WorkflowStage<T, R> {
        private final Function<T, CompletableFuture<R>> operation;
        private final Predicate<T> condition;
        private final Function<T, R> fallback;

        public WorkflowStage(
                Function<T, CompletableFuture<R>> operation,
                Predicate<T> condition,
                Function<T, R> fallback) {
            this.operation = operation;
            this.condition = condition;
            this.fallback = fallback;
        }

        public CompletableFuture<R> execute(T input) {
            if (condition.test(input)) {
                return operation.apply(input)
                        .handle((result, error) -> {
                            if (error != null) {
                                return fallback.apply(input);
                            }
                            return result;
                        });
            }
            return CompletableFuture.completedFuture(
                    fallback.apply(input)
            );
        }
    }

    public   class WorkflowBuilder<T> {
        private final List<WorkflowStage<T, ?>> stages =
                new ArrayList<>();

        public <R> WorkflowBuilder<T> addStage(
                Function<T, CompletableFuture<R>> operation,
                Predicate<T> condition,
                Function<T, R> fallback) {
            stages.add(new WorkflowStage<>(
                    operation,
                    condition,
                    fallback
            ));
            return this;
        }

        public CompletableFuture<T> build(T initialInput) {
            CompletableFuture<T> workflowResult =
                    CompletableFuture.completedFuture(initialInput);

            for (WorkflowStage<T, ?> stage : stages) {
                workflowResult = workflowResult
                        .thenCompose(input ->
                                stage.execute(input)
                                        .thenApply(result -> input)
                        );
            }

            return workflowResult;
        }
    }

    public static void main(String[] args) {
        // 创建一个 WorkflowBuilder 实例


    }
}
